package tt.dz.service.imp.middleware;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.dao.ext.charger.OmsChargerOfflineWhitelistDao;
import tt.dz.dao.ext.charger.OmsChargerRateDao;
import tt.dz.dao.ext.charger.OmsChargerRateRepo;
import tt.dz.dao.ext.dic.OmsDicForwardSrvInfoDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerOfflineWhitelist;
import tt.dz.entity.charger.OmsChargerRate;
import tt.dz.entity.dic.OmsDicForwardSrvInfo;
import tt.dz.entity.exception.BizException;
import tt.dz.service.base.OfflineWhiteListService;
import tt.dz.service.middleware.EncapsulationService;
import tt.dz.service.middleware.MessageService;
import tt.dz.service.middleware.SetService;
import tt.dz.tcp.socket.exception.CreateConnectionFailException;
import tt.dz.tcp.socket.exception.DuplicateInstructionException;
import tt.dz.tcp.socket.exception.RetryFailException;
import tt.dz.util.BinUtils;
import tt.dz.util.OmsConstant;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class SetServiceImpl implements SetService{

	private Log log = LogFactory.getLog(SetServiceImpl.class);

//	@Resource
//	OmsChargerPulseRecordDao omsChargerPulseRecordDao;
//	@Resource
//	OmsChargerTelemetryRecordDao omsChargerTelemetryRecordDao;
	@Resource
	OmsChargerDao omsChargerDao;	
	@Resource
	OmsDicForwardSrvInfoDao omsDicForwardSrvInfoDao;
	@Resource(name = "ev3cMessageServiceImpl")
	MessageService ev3cMessageService;
	@Resource(name = "ev3cEncapsulationServiceImpl")
	EncapsulationService ev3cEncapsulationService;
	@Resource
	OmsChargerOfflineWhitelistDao omsChargerOfflineWhitelistDao;
	@Resource
	OfflineWhiteListService  offlineWhitelistServiceImpl;

	@Resource
	OmsChargerRateDao omsChargerRateDao;
	@Resource
	OmsChargerRateRepo omsChargerRateRepo;

	@Resource
	MessageWrapper messageWrapper;

	public static final int OPER_ADD = 1;
	public static final int OPER_DELETE = 0;


	String chargerId;
	String ev3c_msgHeader = "", ev3c_msgBody = "",protocol_type="",protocol_version="",ev3c_communicationNo ="0001";
	String ev3c_frameCode;//ev3c服务器回复帧代码
	JsonCommon<String> json = new JsonCommon<String>();
	Map<String,String> hashMap = new HashMap<String,String>();
	@Override
	public JsonCommon<String> findHardwareServerIp(Map<String,String> map) {
		protocol_type = map.get("protocol_type");//协议类型  1：EV3C；2：Protocol Translate；3 P2P 
		protocol_version = map.get("protocol_version");
		switch (protocol_type){
			case "1":
				ev3c_frameCode ="30";
				chargerId = map.get("chargerId");
				ev3c_communicationNo = map.get("communicationNo");
				if(StringUtil.isBlank(ev3c_communicationNo)){
					ev3c_communicationNo ="0001";
				}
				ev3c_msgHeader ="68"+"0000"+"01"+"000000"+ev3c_communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
				try {
					ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
				} catch (RetryFailException e) {
					e.printStackTrace();
					json.setCode("400");
					json.setMsg("chargerId "+chargerId+" findHardwareServerIp sendSocket fail "+e.getMessage());
					return json;
				}
				catch (CreateConnectionFailException e)
				{
					e.printStackTrace();
					json.setCode("400");
					json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
					return json;
				} catch (DuplicateInstructionException e) {
					log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
					json.setCode("400");
					json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
					return json;
				}
				json.setCode("200");
				json.setMsg("chargerId : "+chargerId+" findHardwareServerIp send ok");
				json.setPojo(null);
//				switch (protocol_version){
//					case "0101":
//						json = ev3cAnd0101findHardwareServerIp(map);
//						break;
//					case "0102":
//						json = ev3cAnd0102findHardwareServerIp(map);
//						break;
//					case "0103":
//						json = ev3cAnd0103findHardwareServerIp(map);
//						break;
//					default :
//						break;
//				}
//				break;
			default :
				break;
		}
		return json;
	}
	@Override
	public JsonCommon<Map<String, String>> findHardwareServerIpReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");//协议类型  1：EV3C；2：Protocol Translate；3 P2P 
		protocol_version = map.get("protocol_version");
		JsonCommon<Map<String, String>> hashJson = new JsonCommon<Map<String, String>>();
		switch (protocol_type){
			case "1":
				chargerId = map.get("chargerId");
				String main_hardware_ip =map.get("main_hardware_ip");  //
				String main_port = map.get("main_port"); 
				String back_headware_ip = map.get("back_headware_ip"); 
				String back_port = map.get("back_port"); 
				hashMap.put("main_hardware_ip", main_hardware_ip);
				hashMap.put("main_port", main_port);
				hashMap.put("back_headware_ip", back_headware_ip);
				hashMap.put("back_port", back_port);
				hashJson.setPojo(hashMap);
				hashJson.setCode("200");
				hashJson.setMsg("chargerId :"+chargerId+" setHardwareServerIpReturn ");
				//存入redis中
				String key = chargerId+"_server_ip_port";
				RedisClient.putMap(key, hashMap);
			default :
				break;
		}
		return hashJson;
	}
	@Override
	public JsonCommon<String> setHardwareServerIp(Map<String, String> map) {
		protocol_type = map.get("protocol_type");//协议类型  1：EV3C；2：Protocol Translate；3 P2P 
		protocol_version = map.get("protocol_version");
		switch (protocol_type){
			case "1":
				ev3c_frameCode ="32";
				ev3c_communicationNo = map.get("communicationNo");
				if(StringUtil.isBlank(ev3c_communicationNo)){
					ev3c_communicationNo ="0001";
				}
				switch (protocol_version){
					case "0101":
						json = ev3c0101SetHardwareServerIp(map);
						break;
					case "0102":
						json = ev3c0102SetHardwareServerIp(map);
						break;
					case "0103":
						json = ev3c0103SetHardwareServerIp(map);
						break;
					case "0201":
						json = ev3c0201SetHardwareServerIp(map);
						break;	
					default :
						break;
				}
				break;
			default :
				break;
		}
		return json;
	}

	private JsonCommon<String> ev3c0201SetHardwareServerIp(Map<String, String> map)
	{
		String chargerId = map.get("chargerId");

		String main_hardware_ip = map.get("main_hardware_ip");
		main_hardware_ip = StringUtil.ip2HexStr(main_hardware_ip);

		String main_port = map.get("main_port");
		main_port = StringUtil.float10to16ByParamDesc(main_port, 1, 4);

		String back_headware_ip = map.get("back_headware_ip");
		back_headware_ip = StringUtil.ip2HexStr(back_headware_ip);

		String back_port = map.get("back_port");
		back_port = StringUtil.float10to16ByParamDesc(back_port, 1, 4);

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}

		int chargerType = charger.getCharger_type();


		String frameCode = "15";
		String encryption = "00";
		String portNo = "0";
		String activate_time = "00000000000000"; //TODO read this field from front-end screen

//		主服务器		IP地址	BCD码	4
//	    主服务器		端口号	BIN码	2
//		备用服务器	IP地址	BCD码	4
//		备用服务器	端口号	BIN码	2
//		生效时间	            BCD码	7

		String body = main_hardware_ip + main_port + back_headware_ip + back_port + activate_time;
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " SetHardwareServerIp ok ");
			json.setPojo(null);

		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		}
		return json;
	}
	private JsonCommon<String> ev3c0101SetHardwareServerIp(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String main_hardware_ip =map.get("main_hardware_ip");
		main_hardware_ip = StringUtil.ip2HexStrLeftComplement(main_hardware_ip, 2);
		String main_port =map.get("main_port");
		main_port = StringUtil.float10to16ByParamDesc(main_port, 1, 4);
		String back_headware_ip =map.get("back_headware_ip");
		back_headware_ip = StringUtil.ip2HexStrLeftComplement(back_headware_ip, 2);
		String back_port =map.get("back_port");
		back_port = StringUtil.float10to16ByParamDesc(back_port, 1, 4);
		ev3c_msgBody ="00"+StringUtil.now14time()+main_hardware_ip+main_port+back_headware_ip+back_port;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBodyBin(ev3c_msgBody)+"01"+"000000"+ev3c_communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" findHardwareServerIp sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		}
		json.setCode("200");
		json.setMsg("chargerId :"+chargerId+" SetHardwareServerIp ok ");
		json.setPojo(null);
		return json;
	}
	private JsonCommon<String> ev3c0102SetHardwareServerIp(Map<String, String> map) {
		return ev3c0101SetHardwareServerIp(map);
	}
	private JsonCommon<String> ev3c0103SetHardwareServerIp(Map<String, String> map) {
		chargerId = map.get("chargerId");
		String main_hardware_ip =map.get("main_hardware_ip");
		main_hardware_ip = StringUtil.ip2HexStr(main_hardware_ip);
		String main_port =map.get("main_port");
		main_port =StringUtil.float10to16ByParamDesc(main_port, 1, 4);
		String back_headware_ip =map.get("back_headware_ip");
		back_headware_ip = StringUtil.ip2HexStr(back_headware_ip);
		String back_port =map.get("back_port");
		back_port = StringUtil.float10to16ByParamDesc(back_port, 1, 4);
		String is_re_register =map.get("is_re_register");
		if(StringUtil.isBlank(is_re_register)){
			is_re_register ="01";//0x00: 不需重新注册，使用已有设备地址直接在新服务器签到。
			//0x01：需要重置“是否已注册”标记，切换到新服务器后重新注册获取设备地址。
		}
		ev3c_msgBody ="00"+StringUtil.now14time()+main_hardware_ip+main_port+back_headware_ip+back_port+is_re_register;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBodyBin(ev3c_msgBody)+"01"+"000000"+ev3c_communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" findHardwareServerIp sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" findHardwareServerIp sendSocket fail "+e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" findHardwareServerIp sendSocket fail "+e.getMessage());
			return json;
		}
		json.setCode("200");
		json.setMsg("chargerId :"+chargerId+" SetHardwareServerIp ok ");
		json.setPojo(null);
		return json;
	}
	@Override
	public JsonCommon<Map<String, String>> setHardwareServerIpReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");//协议类型  1：EV3C；2：Protocol Translate；3 P2P 
		protocol_version = map.get("protocol_version");
		JsonCommon<Map<String, String>> hashJson = new JsonCommon<Map<String, String>>();
		switch (protocol_type){
			case "1":
				chargerId = map.get("chargerId");
				String effect_type =  map.get("effect_type");  //生效类型  00：立即生效   01:延时生效：TODO如果不是立即生效，则系统就不知道如何处理了
				if(StringUtil.isBlank(effect_type)){
					effect_type ="00";
				}
				int effectDirReal =  StringUtil.sixteen2tenInt(effect_type);//
//				String effectDate = data.substring(52,66);  //生效时间
				String main_hardware_ip =  map.get("main_hardware_ip");
				String main_port = map.get("main_port");
				String back_headware_ip =  map.get("back_headware_ip");
				String back_port =  map.get("back_port");
				int main_port_int = Integer.valueOf(main_port);
				int back_port_int = Integer.valueOf(back_port);
				if(effectDirReal == 0){//query oms_dic_forward_srv_info[桩硬件服务器信息]  查询转发服务器编号 forward_srv_id ；update omscharger
					OmsDicForwardSrvInfo omsDicForwardSrvInfo_query = new OmsDicForwardSrvInfo();
					omsDicForwardSrvInfo_query.setMain_hardware_ip(main_hardware_ip);
					omsDicForwardSrvInfo_query.setMain_port_up(main_port_int);
					omsDicForwardSrvInfo_query.setBack_headware_ip(back_headware_ip);
					omsDicForwardSrvInfo_query.setBack_port_up(back_port_int);
					OmsDicForwardSrvInfo omsDicForwardSrvInfo = omsDicForwardSrvInfoDao.findOneExample(omsDicForwardSrvInfo_query, null , null);
					if(omsDicForwardSrvInfo!=null){
						OmsCharger omsCharger_query = new OmsCharger();
						omsCharger_query.setCharger_id(chargerId);
						List<OmsCharger> omsCharger_list = omsChargerDao.findExample(omsCharger_query, null, null, null, null);
						for(OmsCharger omsCharger :omsCharger_list){
							omsCharger.setForward_srv_id(omsDicForwardSrvInfo.getForward_srv_id());
							omsChargerDao.save(omsCharger);
						}
					}
				}
				hashMap.put("main_hardware_ip", main_hardware_ip);
				hashMap.put("main_port", main_port);
				hashMap.put("back_headware_ip", back_headware_ip);
				hashMap.put("back_port", back_port);
				hashJson.setPojo(hashMap);
				hashJson.setCode("200");
				hashJson.setMsg("chargerId :"+chargerId+" setHardwareServerIpReturn ");
				//存入redis中
				String key = chargerId+"_server_ip_port";
				RedisClient.putMap(key, hashMap);
			default :
				break;
		}
		return hashJson;
	}
	
	@Override
	public JsonCommon<String> setParamReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		if(protocol_type==null){
			protocol_type  = "1";
		}
		if(protocol_version==null){
			protocol_version  = "0103";
		}
		switch (protocol_type) {
		case "1":
//			json.setCode("200");
//			json.setMsg("ok");
//			json.setPojo(null);
			switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				break;
			case "0103":
				json = ev3c0103SetParamReturn(map);
				break;
			case "0201":
				json = ev3c0201SetParamReturn(map);
				break;	
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}
	private JsonCommon<String> ev3c0201SetParamReturn(Map<String, String> map) {
		
		return null;
	}
	//由于目前 6.3.8.1电桩参数查询/设置   最高充电电压 等等是放到设备表中，然后桩表中没有这些字段了，所以没有地方存了。
	private JsonCommon<String> ev3c0103SetParamReturn(Map<String, String> map) {
		return null;
	}

	@Override
	public JsonCommon<String> setWhiteListReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		if(protocol_type==null){
			protocol_type  = "1";
		}
		if(protocol_version==null){
			protocol_version  = "0103";
		}
		switch (protocol_type) {
		case "1":
//			json.setCode("200");
//			json.setMsg("ok");
//			json.setPojo(null);
			switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				break;
			case "0103":
				json = ev3c0103SetWhiteListReturn(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	private JsonCommon<String> ev3c0103SetWhiteListReturn(Map<String, String> map) {
		chargerId = map.get("chargerId");
		omsChargerOfflineWhitelistDao.exec("delete from oms_charger_offline_whitelist where charger_id ='"+chargerId+"'");
		//然后insert这些数据
		List<OmsChargerOfflineWhitelist> list = new ArrayList<OmsChargerOfflineWhitelist>();
//		String whiteList = map.get("whiteList");
		
		String key = chargerId+"_set_whiteList";
		Map<String, String> MapFromRedis = RedisClient.getMap(key);
		String whiteList = MapFromRedis.get("whiteList");
		if(StringUtil.isBlank(whiteList)){
			return OmsConstant.jsonRedisQueryNull;
		}
		String result = map.get("result");
		if(StringUtil.isBlank(result)){
			return OmsConstant.jsonRedisQueryNull;
		}
		if(result.equals("00")){
			return OmsConstant.jsonEv3cExecFail;
		}
		String[] list_str = whiteList.split(",");
		Date now = new Date();
		for(int i =0;i<list_str.length;i++){
			OmsChargerOfflineWhitelist temp = new OmsChargerOfflineWhitelist();
			temp.setCharger_id(chargerId);
			temp.setUser_pay_card(list_str[i]);
			temp.setCreate_time(now);
			temp.setUpdate_time(now);
			temp.setValid_flag(1);
			list.add(temp);
		}
		omsChargerOfflineWhitelistDao.saveList(list);
		return OmsConstant.jsonSuccess;
	}

	@Override
	public JsonCommon<String> findWhiteListReturn(Map<String, String> map) {
		String chargerId = map.get("chargerId");
//		String whiteList_no = map.get("whiteList_no");
//		String whiteListStr = map.get("whiteList");
		String key = chargerId+"_whiteList";
		StringUtil.removeNullValue(map);
		RedisClient.putMap(key, map);
		return OmsConstant.jsonSuccess;
	}
	@Override
	public JsonCommon<String> setTimeReturn(Map<String, String> map) {
		
		return null;
	}
	@Override
	public JsonCommon<String> findRateReturn(Map<String, String> map) {
		String key =map.get("chargerId")+"_find_rate";
		StringUtil.removeNullValue(map);
		RedisClient.putMap(key, map);
		return OmsConstant.jsonSuccess;
	}
	@Override
	public JsonCommon<String> setRateReturn(Map<String, String> map) {
		String key =map.get("chargerId")+"_set_rate";
		StringUtil.removeNullValue(map);
		RedisClient.putMap(key, map);
		return OmsConstant.jsonSuccess;
	}
	@Override
	public JsonCommon<String> setQrCodeReturn(Map<String, String> map) {
		String chargerId = map.get("chargerId");
		String qrCode = map.get("qrCode");
		OmsCharger omsCharger_query = new OmsCharger();
		omsCharger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(omsCharger_query, null, null);
		if(charger!=null){
			charger.setQr_code(qrCode);
			omsChargerDao.updateObject(charger);
		}
		return OmsConstant.jsonSuccess;
	}

	@Override
	public JsonCommon<String> findRate(Map<String, String> map)
	{
		//		ev3c_communicationNo ="0001";
		String chargerId = map.get("chargerId");
		String feetype = map.get("feetype");
		String frameCode = "36";
		String body = "000" + feetype;
		String portNo = "0";
		String encryption = "00";

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}

		int chargerType = charger.getCharger_type();
		ev3c_msgBody = "";
//		String msg = messageWrapper.wrapSendingMsg(ev3c_msgBody, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);
		String oms_msg_jrnl = StringUtil.now14time();
		String msg = "680000010000000001"+chargerId+frameCode+oms_msg_jrnl;
		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket fail " + e.getMessage());
			return json;
		}
		json.setCode("200");
		json.setMsg("chargerId " + chargerId + " findHardwareServerIp sendSocket success ");
		return json;
	}

	@Override
	public void sendFee(String chargerId) throws BizException, RetryFailException, CreateConnectionFailException
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger =  omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("Charger not found for charger id " + chargerId);


		if("0101".equals(charger.getProtocol_version()) || "0102".equals(charger.getProtocol_version()) || "0103".equals(charger.getProtocol_version()))
		{
			sendFeeFor01(charger);
		}
		else if("0201".equals(charger.getProtocol_version()))
		{
			sendFeeFor02(charger);
		}
		else
			throw new BizException("invalid protocol version of charger");

	}

	private void sendFeeFor02(OmsCharger charger) throws CreateConnectionFailException, BizException, RetryFailException
	{
		if (charger.getRate_schema_charge_fee() != null)
			sendFeeFor02BySchemaNo(charger.getCharger_id(), charger.getRate_schema_charge_fee(), charger.getCharger_type());

		if (charger.getRate_schema_service_fee() != null)
			sendFeeFor02BySchemaNo(charger.getCharger_id(), charger.getRate_schema_service_fee(), charger.getCharger_type());
	}

	private void sendFeeFor01(OmsCharger charger) throws BizException, RetryFailException, CreateConnectionFailException
	{
//		Map<String, String> map = new HashMap<String, String>();
		// 1.预约费费率方案号(oms_charger_rate[电桩费率表])
		//		OmsChargerRate omsChargerRate_query_bespeak = new OmsChargerRate();
		//		omsChargerRate_query_bespeak.setRate_schema(charger.getRate_schema_bespeak_fee());
		//		OmsChargerRate omsChargerRate_bespeak = omsChargerRateService.findOneExample(omsChargerRate_query_bespeak, null, null);
		//		if (StringUtil.objectIsNull(omsChargerRate_bespeak)) {
		//			return OmsConstant.jsonFail;
		//		}
		// 2.电费费率方案号(oms_charger_rate[电桩费率表])
		// charge_mode(收费模式):0:按时间收费,1:按次数收费.后期考虑将费率方案分离,兼容现有模式。
		// fee_type(费用类型):1:预约费用;2:充电费用;3:充电服务费,0为尚未分配类型的费用
		List<OmsChargerRate> omsChargerRate_charge = omsChargerRateDao.findListByCondition(new OmsChargerRate(), " where 1=1 and rate_schema = " + charger.getRate_schema_charge_fee().intValue() + " and charge_mode = 0 and fee_type = 2 and valid_flag = 1 ORDER BY serial_no ASC");
		if (omsChargerRate_charge == null || omsChargerRate_charge.size() != 4)
			throw new BizException("Rate schema is empty or the number of time section is not 4");

		// 3.服务费费率方案号(oms_charger_rate[电桩费率表])
		OmsChargerRate omsChargerRate_query_service = new OmsChargerRate();
		omsChargerRate_query_service.setRate_schema(charger.getRate_schema_service_fee());
		omsChargerRate_query_service.setValid_flag(1);
		OmsChargerRate omsChargerRate_service = omsChargerRateDao.findOneExample(omsChargerRate_query_service, "end_time", "desc");
		if (omsChargerRate_service == null)
			throw new BizException("service fee schema not found");

		String ev3c_communicationNo = "0001";
		String chargerId = charger.getCharger_id();
		String rate1 = omsChargerRate_charge.get(0).getRate().toString();
		String rate2 = omsChargerRate_charge.get(1).getRate().toString();
		String rate3 = omsChargerRate_charge.get(2).getRate().toString();
		String rate4 = omsChargerRate_charge.get(3).getRate().toString();
		String fee_rate = omsChargerRate_service.getRate().toString();
		String time1 = omsChargerRate_charge.get(0).getEnd_time().toString().substring(0, 5).replace(":", "");
		String time2 = omsChargerRate_charge.get(1).getEnd_time().toString().substring(0, 5).replace(":", "");
		String time3 = omsChargerRate_charge.get(2).getEnd_time().toString().substring(0, 5).replace(":", "");
		String time_rate = StringUtil.ThreetimeTo48(time1, time2, time3);
		String rate1_bin = StringUtil.float10to16ByParamDesc(rate1, 100, 4);
		String rate2_bin = StringUtil.float10to16ByParamDesc(rate2, 100, 4);
		String rate3_bin = StringUtil.float10to16ByParamDesc(rate3, 100, 4);
		String rate4_bin = StringUtil.float10to16ByParamDesc(rate4, 100, 4);
		String fee_rate_bin = StringUtil.float10to16ByParamDesc(fee_rate, 100, 4);
		ev3c_frameCode = "38";
		ev3c_msgBody = rate1_bin + rate2_bin + rate3_bin + rate4_bin + fee_rate_bin + time_rate;
		ev3c_msgHeader = "68" + StringUtil.ev3cMsgBodyBin(ev3c_msgBody) + "01" + "000000" + ev3c_communicationNo + chargerId + ev3c_frameCode + StringUtil.now14time();
		try
		{
			ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	private void sendFeeFor02BySchemaNo(String chargerId, Integer schema_no, int chargerType) throws BizException, RetryFailException, CreateConnectionFailException
	{
		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";

		List<OmsChargerRate> list_ratevo = omsChargerRateDao.findListByCondition(new OmsChargerRate(), " where rate_schema = " + schema_no + " ");
		if (list_ratevo == null || list_ratevo.isEmpty())
			throw new BizException("schema No.: " + schema_no + " not found ");

		OmsChargerRate default_vo = list_ratevo.get(0);

		StringBuffer body = new StringBuffer("01");
		SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
		if (OmsConstant.ChargingPaymentMeans.Charging == default_vo.getFee_type())
		{
			body.append(String.format("%02d", OmsConstant.ChargingPaymentMeans.Charging));
			body.append(String.format("%02d", list_ratevo.size()));
			for (OmsChargerRate vo : list_ratevo)
			{
				body.append("00000000").append(sdf.format(vo.getEnd_time()));
				body.append(BinUtils.convertIntToReversedHexString(vo.getRate().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(), 4));
			}
		}
		else if (OmsConstant.ChargingPaymentMeans.ChargeService == default_vo.getFee_type())
		{
			body.append(String.format("%02d", OmsConstant.ChargingPaymentMeans.ChargeService));
			body.append(String.format("%02d", default_vo.getCharge_mode()));
			if (default_vo.getCharge_mode() == 0)//0按时间, 1按次数
				body.append("FFFF");
			else
				body.append(BinUtils.convertIntToReversedHexString(default_vo.getRate().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(), 4));

			if (default_vo.getCharge_mode() == 0)//0按时间, 1按次数
			{
				body.append(String.format("%02d", list_ratevo.size()));
				for (OmsChargerRate vo : list_ratevo)
				{
					body.append("00000000").append(sdf.format(vo.getEnd_time()));
					body.append(BinUtils.convertIntToReversedHexString(vo.getRate().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue(), 4));
				}
			}
		}

		String msg = messageWrapper.wrapSendingMsg(body.toString(), frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	@Override
	public JsonCommon<String> setQrCode(Map<String, String> map) throws RetryFailException, CreateConnectionFailException, BizException
	{
		String chargerId = map.get("chargerId");
		String frameCode;

		log.debug(map);
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			throw new BizException("Charger not found");
		}

		String body = "0101" + map.get("qrCode");
		String msg;
		String chargerType;

		if("0201".equals(charger.getProtocol_version()))
		{
			if(charger.getCharger_type() == 1)
				chargerType = OmsConstant.ChargerType.DC;
			else if(charger.getCharger_type() == 2)
				chargerType = OmsConstant.ChargerType.AC;
			else
				throw new BizException("invalid charger type");
			frameCode = "21";
			msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, chargerType, "1", "00");
		}
		else if("0101".equals(charger.getProtocol_version()) || "0102".equals(charger.getProtocol_version()))
		{
			frameCode = "77";
			msg = "680600010000000001".concat(chargerId).concat(frameCode).concat(StringUtil.now14time()).concat(map.get("qrCode"));
		}
		else
			throw new BizException("Invalid charger protocol");


		try {
			ev3cMessageService.sendNoWait(msg, chargerId);
		} catch (RetryFailException e) {
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
		json.setCode("200");
		json.setMsg("chargerId "+chargerId+" setQrCode sendSocket success ");
		return json;
	}
	@Override
	public JsonCommon<String> findWhiteList(Map<String, String> map)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}

		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";
		String body = "0005";
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " findUserCardOnCharger ok ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + "  findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		return json;
	}

	@Override
	public void setWhiteList(String chargerId, List<String> list_userCard, int oper) throws BizException, RetryFailException, CreateConnectionFailException
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("charger not found for chargerId:" + chargerId);

		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";

		StringBuffer body = new StringBuffer("0105");

		if (oper == OPER_ADD)
			body.append("01");
		else if (oper == OPER_DELETE)
			body.append("02");
		else
			throw new BizException("invalid operation");

		body.append(String.format("%02d", list_userCard.size()));
		for (String userCard : list_userCard)
		{
			if (userCard == null || userCard.length() != 20)
				throw new BizException("card number is null or length of user card is not 20");
			body.append(userCard);
		}

		String msg = messageWrapper.wrapSendingMsg(body.toString(), frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}


	@Override
	public JsonCommon<String> setParam(Map<String, String> map)
	{
		String ev3c_msg = ev3cEncapsulationService.setParam(map);
		try
		{
			ev3cMessageService.sendNoWait(ev3c_msg, chargerId);
//			String key = chargerId + "_find_param";
//			StringUtil.removeNullValue(map);
//			RedisClient.putMap(key, map);
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " setParam sendSocket fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " setParam sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " setParam sendSocket fail " + e.getMessage());
		}
		json.setCode("200");
		json.setMsg("chargerId " + chargerId + " setParam sendSocket success ");
		return json;
	}
	@Override
	public JsonCommon<String> ev3c2setHardwareServerIpReturn(Map<String, String> map) {
		//目前2.0协议这里这个返回什么也不用做，因为对应表暂时不体现作用。
		return null;
	}

	@Override
	public JsonCommon<String> setTimer(String chargerId, String timer)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}

		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";

		String body = "0100" + timer;
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " Set Timer ok ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + "  Set Timer fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " Set Timer fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " Set Timer fail " + e.getMessage());
			return json;
		}
		return json;

	}

	@Override
	public void setIdentification(String chargerId) throws BizException, RetryFailException, CreateConnectionFailException
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("charger not found for chargerId:" + chargerId);

		if(StringUtils.isEmpty(charger.getSerial_no()))
			throw new BizException("Empty serial no of this charger");

		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";

		String body = "0108" + BinUtils.convertIntToReversedHexString(Integer.valueOf(charger.getSerial_no()), 2);
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	@Override
	public JsonCommon<String> findChargerStatus(String chargerId, String portNo)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}


		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";

		String body = "0007";
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " Set Timer ok ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + "  Set Timer fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " Set Timer fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " Set Timer fail " + e.getMessage());
			return json;
		}
		return json;
	}

	@Override
	public JsonCommon<String> findUserCardOnCharger(String chargerId)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}


		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";
		String body = "0006";
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " findUserCardOnCharger ok ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + "  findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		return json;
	}

	@Override
	public JsonCommon<String> findIdentification(String chargerId)
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}


		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";
		String body = "0008";
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId :" + chargerId + " findUserCardOnCharger ok ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + "  findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " findUserCardOnCharger fail " + e.getMessage());
			return json;
		}
		return json;
	}

	@Override
	public JsonCommon<String> summon(Map<String, String> map) {
		String ev3c_msg = ev3cEncapsulationService.summon(map);
		try {
			ev3cMessageService.sendNoWait(ev3c_msg, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" summon sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" summon sendSocket fail "+e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" summon sendSocket fail "+e.getMessage());
			return json;
		}
		json.setCode("200");
		json.setMsg("chargerId "+chargerId+" summon sendSocket success ");
		return json;
	}

	@Override
	public void setState(String chargerId, String state) throws BizException, RetryFailException, CreateConnectionFailException
	{
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null)
			throw new BizException("charger not found for chargerId:" + chargerId);

		int chargerType = charger.getCharger_type();

		String frameCode = "21";
		String encryption = "00";
		String portNo = "0";

		String body = "0107" + state;

		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);

		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}
}
